package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.BrandMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.BrandAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.BrandUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Brand;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.AlbumStandardVO;
import cn.tedu.csmall.product.pojo.vo.BrandListItemVO;
import cn.tedu.csmall.product.pojo.vo.BrandStandardVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.repo.IBrandRedisRepository;
import cn.tedu.csmall.product.service.IBrandService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 处理品牌数据业务的实现类
 * @author 何惠民
 * @version 0.0.1
 */
@Slf4j
@Service
public class BrandServiceImpl implements IBrandService {

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    BrandCategoryMapper brandCategoryMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    private IBrandRedisRepository brandRedisRepository;

    public BrandServiceImpl() {
        log.debug("创建业务对象:BrandServiceImpl");
    }

    @Override
    public void addNew(BrandAddNewDTO brandAddNewDTO) {
        log.debug("开始处理[添加品牌]的业务,参数:{}",brandAddNewDTO);
        //从参数对象中品牌名称
        String brandName = brandAddNewDTO.getName();
        //检查品牌名称是否已经被占用
        log.debug("检查品牌名称是否被占用");
        int count = brandMapper.countByName(brandName);
        if (count > 0){
            //是:品牌名称被占用,添加品牌失败,抛出异常
            String message = "添加失败,品牌名称被占用";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        //否:品牌名称没有被占用,则向品牌表中插入数据
        log.debug("品牌名称没有被占用,则向品牌表中插入数据");
        Brand brand = new Brand();
        BeanUtils.copyProperties(brandAddNewDTO, brand);
        log.debug("即将插入品牌数据:{}", brand);
        int rows = brandMapper.insert(brand);
        if (rows != 1){
            String message = "添加品牌失败,服务器忙,请稍后再尝试!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
        log.debug("插入品牌数据完成");
    }

    @Override
    public void deleteById(Long id) {
        log.debug("开始处理[删除品牌]的业务,参数:{}",id);
        //查询要删除的相册是否存在
        BrandStandardVO queryResult = brandMapper.getStandardById(id);
        //是否为null
        if (queryResult == null){
            String message = "删除品牌失败,尝试删除的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //检查是否存在品牌关联到此品牌,如果存在,则不允许删除
        int count = brandCategoryMapper.countByBrandId(id);
        if (count > 0) {
            String message = "删除品牌失败，此相册存在关联的品牌数据！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //检查是否存在SPU关联到此品牌,如果存在,则不允许删除
        int countSpu = spuMapper.countByBrandId(id);
        if (countSpu > 0) {
            String message = "删除品牌失败，此相册存在关联的SPU数据！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        //调用mapper对象的deleteById()方法执行删除
        log.debug("即将执行删除,参数:{}",id);
        int rows = brandMapper.deleteById(id);
        if (rows != 1){
            String message = "删除类别失败,服务器忙,请稍后再尝试!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_DELETE,message);
        }
    }

    @Override
    public void update(BrandUpdateDTO brandUpdateDTO) {
        log.debug("开始处理修改品牌的业务参数:{}",brandUpdateDTO);
        String name = brandUpdateDTO.getName();
        int rows = brandMapper.countByName(name);
        if (rows > 0){
            BrandStandardVO brandStandardVO = brandMapper.getStandardById(brandUpdateDTO.getId());
            if (!brandStandardVO.getName().equals(brandUpdateDTO.getName())){
                String message = "修改失败,修改后的名称已经存在,请更换";
                log.debug(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
            }
        }
        Brand brand = new Brand();
        BeanUtils.copyProperties(brandUpdateDTO, brand);
        rows = brandMapper.update(brand);
        if (rows != 1){
            String message = "修改品牌失败,服务器忙,请稍后再尝试!";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id,1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id,0);
    }


    private void updateEnableById(Long id, Integer enable){
        log.debug("开始处理[更新品牌是否启用]的业务,参数:{}",id);
        //id值为1的品牌不允许删除 root
        if (id.equals(1)){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "品牌失败,尝试修改的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        // 查询要删除的品牌是否存在
        BrandStandardVO queryResult = brandMapper.getStandardById(id);
        //是否为null
        if (queryResult == null){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "品牌失败,尝试修改的数据不存在";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //判断enable和参数enable1是否相同
        if (queryResult.getEnable().equals(enable)){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "品牌失败,改品牌已经" + s[enable];
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        Brand brand = new Brand();
        brand.setId(id);
        brand.setEnable(enable);
        int rows = brandMapper.update(brand);
        if (rows != 1){
            String[] s = {"禁用","启用"};
            String message = s[enable] + "品牌失败,尝试修改的数据不存在";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }

    @Override
    public BrandStandardVO getStandardById(Long id) {
        log.debug("开始处理[查询品牌详情]的业务,参数:{}",id);
        //从缓存中获取数据
        log.debug("将从Redis中获取数据");
        BrandStandardVO brand = brandRedisRepository.get(id);
        //判断获取到结果是否不为null
        if (brand != null){
            //--是:直接返回
            log.debug("命中缓存,即将返回{}",brand);
            return brand;
        }
        //无缓存数据 ,从数据库中查找数据
        log.debug("未命中,即将从数据库中查询");
        brand = brandMapper.getStandardById(id);
        //--判断查询到的结果是否为null
        if (brand == null){
            //--是: 抛出异常
            String message = "没有查询到id为"+id+"的品牌详情数据";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        //将查询结果写入缓存并返回
        log.debug("从数据库查询到有效结果,即将返回{}",brand);
        brandRedisRepository.save(brand);
        log.debug("根据id{}查询到品牌详情数据{}",id,brand);
        return brand;
    }

    @Override
    public List<BrandListItemVO> list() {
        log.debug("开始处理[查询品牌列表]的业务,无参数");
//        List<BrandListItemVO> list = brandMapper.list();
//        brandRedisRepository.save(list);
//        return brandMapper.list();
        return brandRedisRepository.list();
    }

    @Override
    public void rebuildCache() {
        log.debug("准备删除Redis中的缓存数据");
        brandRedisRepository.deleteALL();

        log.debug("准备从数据库中读取品牌列表....");
        List<BrandListItemVO> list = brandMapper.list();
        log.debug("从数据库中读取品牌列表完成....");

        log.debug("准备向Redis中写入品牌列表....");
        brandRedisRepository.save(list);
        log.debug("向Redis中写入品牌列表完成....");

        log.debug("准备将各品牌详情写入到Redis缓存");
        for (BrandListItemVO brand: list){
            brandRedisRepository.save(brandMapper.getStandardById(brand.getId()));
        }
    }
}
